import { Request, Response, NextFunction } from 'express';
import * as bcrypt from 'bcryptjs';
import { prisma } from '../../config/database';
import { logger } from '../../utils/logger';
import { ConfigUtils } from '../../config';
import { BaseController } from '../../utils/autoBind';
import { ResponseUtils } from '../../utils/responseUtils';
import { 
  BUSINESS_ERROR_CODES, 
  VALIDATION_ERROR_CODES,
  COMMON_ERROR_CODES
} from '../../utils/errorCodes';
import { getFileUrl, deleteFile } from '../../middleware/upload';

export class ClientUserController extends BaseController {
  // 获取当前用户信息
  async getProfile(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const userId = (req as any).user?.id;
      if (!userId) {
        ResponseUtils.sendError(res, COMMON_ERROR_CODES.UNAUTHORIZED, '用户未登录');
        return;
      }

      const user = await prisma.user.findUnique({
        where: { id: userId },
        select: {
          id: true,
          username: true,
          email: true,
          realName: true,
          avatar: true,
          phone: true,
          status: true,
          lastLoginAt: true,
          createdAt: true,
          updatedAt: true,
          userRoles: {
            include: {
              role: {
                select: {
                  id: true,
                  name: true,
                  description: true,
                  rolePermissions: {
                    include: {
                      permission: {
                        select: {
                          id: true,
                          code: true,
                          name: true,
                          module: true
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      });

      if (!user) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_NOT_FOUND, '用户不存在');
        return;
      }

      // 构建用户信息
      const userInfo = {
        ...user,
        avatar: user.avatar ? getFileUrl(user.avatar) : null,
        roles: user.userRoles.map(ur => ({
          id: ur.role.id,
          name: ur.role.name,
          description: ur.role.description,
          permissions: ur.role.rolePermissions.map(rp => ({
            id: rp.permission.id,
            code: rp.permission.code,
            name: rp.permission.name,
            module: rp.permission.module
          }))
        }))
      };

      ResponseUtils.success(res, userInfo, '获取个人资料成功');
    } catch (error) {
      next(error);
    }
  }

  // 更新个人资料
  async updateProfile(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const userId = (req as any).user?.id;
      if (!userId) {
        ResponseUtils.sendError(res, COMMON_ERROR_CODES.UNAUTHORIZED, '用户未登录');
        return;
      }

      const { realName, email, phone } = req.body;

      // 检查邮箱是否已被其他用户使用
      if (email) {
        const existingUser = await prisma.user.findFirst({
          where: {
            email,
            id: { not: userId }
          }
        });

        if (existingUser) {
          ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_ALREADY_EXISTS, '邮箱已被其他用户使用');
          return;
        }
      }

      // 更新用户信息
      const updatedUser = await prisma.user.update({
        where: { id: userId },
        data: {
          realName: realName || undefined,
          email: email || undefined,
          phone: phone || undefined
        },
        select: {
          id: true,
          username: true,
          email: true,
          realName: true,
          avatar: true,
          phone: true,
          status: true,
          lastLoginAt: true,
          createdAt: true,
          updatedAt: true
        }
      });

      ResponseUtils.success(res, {
        ...updatedUser,
        avatar: updatedUser.avatar ? getFileUrl(updatedUser.avatar) : null
      }, '个人资料更新成功');
    } catch (error) {
      next(error);
    }
  }

  // 修改密码
  async changePassword(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const userId = (req as any).user?.id;
      if (!userId) {
        ResponseUtils.sendError(res, COMMON_ERROR_CODES.UNAUTHORIZED, '用户未登录');
        return;
      }

      const { currentPassword, newPassword } = req.body;

      if (!currentPassword || !newPassword) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.REQUIRED_FIELD_MISSING, '当前密码和新密码不能为空');
        return;
      }

      // 获取用户信息
      const user = await prisma.user.findUnique({
        where: { id: userId }
      });

      if (!user) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_NOT_FOUND, '用户不存在');
        return;
      }

      // 验证当前密码
      const isCurrentPasswordValid = await bcrypt.compare(currentPassword, user.password);
      if (!isCurrentPasswordValid) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.PASSWORD_INCORRECT, '当前密码错误');
        return;
      }

      // 加密新密码
      const saltRounds = ConfigUtils.getBcryptRounds();
      const hashedNewPassword = await bcrypt.hash(newPassword, saltRounds);

      // 更新密码
      await prisma.user.update({
        where: { id: userId },
        data: { password: hashedNewPassword }
      });

      ResponseUtils.success(res, null, '密码修改成功');
    } catch (error) {
      next(error);
    }
  }

  // 上传头像
  async uploadAvatar(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const userId = (req as any).user?.id;
      if (!userId) {
        ResponseUtils.sendError(res, COMMON_ERROR_CODES.UNAUTHORIZED, '用户未登录');
        return;
      }

      if (!req.file) {
        ResponseUtils.sendError(res, VALIDATION_ERROR_CODES.REQUIRED_FIELD_MISSING, '请选择要上传的头像文件');
        return;
      }

      // 获取用户当前头像
      const user = await prisma.user.findUnique({
        where: { id: userId },
        select: { avatar: true }
      });

      if (!user) {
        ResponseUtils.sendError(res, BUSINESS_ERROR_CODES.USER_NOT_FOUND, '用户不存在');
        return;
      }

      // 删除旧头像文件
      if (user.avatar) {
        try {
          await deleteFile(user.avatar);
        } catch (error) {
          logger.warn('删除旧头像文件失败:', error);
        }
      }

      // 更新用户头像
      const updatedUser = await prisma.user.update({
        where: { id: userId },
        data: { avatar: req.file.filename },
        select: {
          id: true,
          username: true,
          email: true,
          realName: true,
          avatar: true,
          phone: true,
          status: true
        }
      });

      ResponseUtils.success(res, {
        ...updatedUser,
        avatar: getFileUrl(updatedUser.avatar!)
      }, '头像上传成功');
    } catch (error) {
      next(error);
    }
  }
} 